<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>03_计算属性和监视</title>
	</head>
	<body>
		<!--
			1. 计算属性
			  在computed属性对象中定义计算属性的方法
			  在页面中使用 {{方法名}} 来显示计算的结果
			2. 监视属性:
			  通过vm对象的$watch()或watch配置来监视指定的属性
			  当属性变化时, 回调函数自动调用, 在函数内部进行计算
			3. 计算属性高级:
			  通过getter/setter实现对属性数据的显示和监视
			  计算属性存在缓存, 多次读取只执行一次getter计算
			  
			  getter:get
			  setter:set
		-->
		<div id="demo">
			姓: <input type="text" placeholder="First Name" v-model="firstName"><br>
			名: <input type="text" placeholder="Last Name"  v-model="lastName"><br>
			<!--fullName1是根据fistName和lastName计算产生-->
			姓名1(单向):(by computed) <input type="text" placeholder="Full Name1" v-model="fullName1"><br>
			姓名2(单向):(by watch) <input type="text" placeholder="Full Name2" v-model="fullName2"><br>
			
			姓名3(双向):(by computed set get) <input type="text" placeholder="Full Name3" v-model="fullName3"><br>

			<hr />
			
			<!-- 计算属性存在缓存 通过方法名为key 缓存 -->
			<p>{{fullName1}}</p>
			<p>{{fullName1}}</p>
			<p>{{fullName1}}</p>
		</div>

		<script type="text/javascript" src="../js/vue.js"></script>
		<script type="text/javascript">
			//new Vue() 创建一个Vue的实例对象  
			//el:  DOM 元素作为 Vue 实例的挂载目标  
			//data:   Vue 实例的数据对象。 
			//methods:   methods 将被混入到 Vue 实例中。
			//computed: 计算属性将被混入到 Vue 实例中。所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例。 
			//wacth: 一个对象，键是需要观察的表达式，值是对应回调函数。值也可以是方法名，或者包含选项的对象。
			         //Vue 实例将会在实例化时调用 $watch()，遍历 watch 对象的每一个属性。
			const vm = new Vue({  
				el: '#demo',
				data: {
					firstName: 'A',
					lastName: 'B',
					fullName2: 'A B'
				},
				//方法
				methods:{},
				
				
			    //计算属性配置: 值为对象
				computed: {
					//什么时候执行:初始化显示/相关的data属性数据发生改变
					//计算并返回当前的值
					fullName1:function() { // 属性的get()
						console.log('fullName1()', this)
						return this.firstName + ' ' + this.lastName
					},

					fullName3: {
						// 当获取当前属性值时自动调用, 将返回值(根据相关的其它属性数据)作为属性值
						//回调函数 计算并返回当前属性的值
						//1.你定义的,2.你没有调用,3.但最终它执行了
						//什么时候调用？当需要读取当前属性值时回调,根据相关的数据计算并返回当前属性的值
						// 用来做什么的？
						get() {
							console.log('fullName3 get()')
							return this.firstName + ' ' + this.lastName
						},
						// 当属性值发生了改变时自动调用, 监视当前属性值变化, 同步更新相关的其它属性值
						//set为监视
						set(value) { // fullName3的最新value值  A-B23
							console.log('fullName3 set()', value)
							// 更新firstName和lastName
							const names = value.split(' ')
							this.firstName = names[0]
							this.lastName = names[1]
						}
					}
				},

				//监视watch 
				watch: {
					// 配置监视firstName
					firstName: function(value) { // 相当于属性的set
						console.log('watch firstName', value)
						// 更新fullName2  this就是vm的实例对象
						this.fullName2 = value + ' ' + this.lastName
					}
				}
			})

			// 监视lastName
			vm.$watch('lastName', function(value) {
				console.log('$watch lastName', value)
				// 更新fullName2
				this.fullName2 = this.firstName + ' ' + value
			})
			
		</script>
	</body>
</html>
